package com.hanxiaozhang.threadbase1ndedition.no4lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 〈一句话功能简述〉<br>
 * 〈ReentrantLock的tryLock〉
 * <p>
 * ReentrantLock可以使用tryLock()进行"尝试锁定"，
 * 无法锁定或者在指定时间内无法锁定，线程可以自己决定是否继续等待
 *
 * @author hanxinghua
 * @create 2021/11/11
 * @since 1.0.0
 */
public class No2ReentrantLockTryLock {

    private Lock lock = new ReentrantLock();

    public void method1() {
        lock.lock();
        try {
            for (int i = 0; i < 3; i++) {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 使用tryLock进行尝试锁定，不管锁定与否，方法都将继续执行
     * 可以根据tryLock的返回值来判定是否锁定
     * 也可以指定tryLock的时间，由于tryLock(time)抛出异常，所以要注意unclock的处理，必须放到finally中
     */
    public void method2() {

//        // tryLock()
//        boolean locked = lock.tryLock();
//        try {
//            System.out.println("method2 get lock is " + locked);
//        } finally {
//            if (locked) {
//                lock.unlock();
//            }
//        }

        // tryLock(long time, TimeUnit unit) throws InterruptedException
        boolean locked = false;
        try {
            // 等待时间 改成 1 或 5 比较
            locked = lock.tryLock(1, TimeUnit.SECONDS);
            System.out.println("method2 get lock is " + locked);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (locked) {
                lock.unlock();
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        No2ReentrantLockTryLock example = new No2ReentrantLockTryLock();
        new Thread(example::method1).start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(example::method2).start();
    }

}
